package vboot.core.module.bpm.proc.main;

import cn.hutool.core.util.StrUtil;
import cn.hutool.script.ScriptRuntimeException;
import cn.hutool.script.ScriptUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import vboot.core.common.mvc.dao.JdbcDao;
import vboot.core.common.mvc.pojo.ZidNamePid;

import javax.script.CompiledScript;
import javax.script.ScriptException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Component
public class BpmProcMainHand {

    public Znode procFlow(Zbpm zbpm, List<Znode> list, Znode znode) {
        //根据tmpid寻找xml的filename
        SAXReader reader = new SAXReader();
        Reader stringReader = new StringReader(zbpm.getChxml());
        Document document = null;
        try {
            document = reader.read(stringReader);
        } catch (DocumentException e) {
            System.out.println("xml解析异常");
            e.printStackTrace();
        }
        Element rootNode = document.getRootElement();
        Iterator<Element> it = rootNode.elementIterator();
        //查找当前节点的目标节点，如果已有（比如是驳回返回的）则不需要额外查找
        if (znode.getTarno() == null) {
            while (it.hasNext()) {
                Element node = it.next();
                if ("sequenceFlow".equals(node.getName())) {
                    if (znode.getFacno().equals(node.attribute("sourceRef").getValue())) {
//                    nextNode.setId(node.attribute("targetRef").getValue());
                        znode.setTarno(node.attribute("targetRef").getValue());
                        break;
                    }
                }
            }
        }
        Zcond zcond=new Zcond();
        zcond.setProid(zbpm.getProid());
        zcond.setModty(zbpm.getModty());
        //判断nextNode是否为审批节点
        return nodeFlow(zcond,rootNode, list, znode);
    }


    //节点流转
    //判断节点是否为审批节点，如果为审批节点则取处理人
    //      如果是条件分支，则根据分支条件流转到下一个节点，直到找到审批节点
    private Znode nodeFlow(Zcond zcond,Element rootNode, List<Znode> list, Znode znode) {
        if ("NE".equals(znode.getTarno())) {
            znode.setTarna("结束节点");
            Znode endNode = new Znode();
            endNode.setFacno("NE");
            endNode.setFacna("结束节点");
            endNode.setFacty("end");
            return endNode;
        }
        Iterator<Element> it = rootNode.elementIterator();
        String userIds = "";
        while (it.hasNext()) {
            Element node = it.next();
            if ("task".equals(node.getName()) || "userTask".equals(node.getName())) {//节点为审批节点
                if (znode.getTarno().equals(node.attribute("id").getValue())) {

                    userIds = node.attribute("hamen").getValue();
                    znode.setTarna(node.attribute("name").getValue());
                    System.out.println(znode);
                    //list.add(znode);
                    Znode nextNode = new Znode();
                    nextNode.setFacno(znode.getTarno());
                    nextNode.setFacna(znode.getTarna());
                    nextNode.setFacty("review");
                    nextNode.setExmen(userIds);
                    nextNode.setFlway(node.attribute("flway").getValue());
                    return nextNode;

//                    System.out.println("进入了：task");
//                    Iterator<Element> sonit = node.elementIterator();
//                    while (sonit.hasNext()) {
//                        Element son = sonit.next();
//                        if ("extensionElements".equals(son.getName())) {
//                            System.out.println("进入了：extensionElements");
//                            Iterator<Element> sunit = son.elementIterator();
//                            while (sunit.hasNext()) {
//                                Element sun = sunit.next();
//                                if ("formProperty".equals(sun.getName())) {
//                                    System.out.println("进入了：formProperty");
//                                    if ("userid".equals(sun.attribute("id").getValue())) {
//                                        userid = sun.attribute("name").getValue();
//                                        znode.setTarna(node.attribute("name").getValue());
//                                        System.out.println(znode);
//                                        //list.add(znode);
//                                        Znode nextNode = new Znode();
//                                        nextNode.setFacno(znode.getTarno());
//                                        nextNode.setFacna(znode.getTarna());
//                                        nextNode.setFacty("review");
//                                        nextNode.setExman(userid);
//                                        return nextNode;
//                                    }
//                                }
//                            }
//                            break;
//                        }
//                    }
                }
            } else if ("exclusiveGateway".equals(node.getName())) {//节点为条件分支
                String nextNodeId = "";
                if (znode.getTarno().equals(node.attribute("id").getValue())) {
                    znode.setTarna(node.attribute("name").getValue());
                    //list.add(znode);
                    it = rootNode.elementIterator();
                    while (it.hasNext()) {
                        Element xnode = it.next();
                        if ("sequenceFlow".equals(xnode.getName())) {
                            if (znode.getTarno().equals(xnode.attribute("sourceRef").getValue())) {

                                if(checkConds(zcond,xnode.attribute("conds").getValue())){
                                    nextNodeId = xnode.attribute("targetRef").getValue();
                                    System.out.println("条件分支转到:" + nextNodeId);
                                    Znode nextNode = new Znode();
                                    nextNode.setFacno(znode.getTarno());
                                    nextNode.setFacna(znode.getTarna());
                                    nextNode.setFacty("condtion");
                                    nextNode.setTarno(nextNodeId);
                                    list.add(nextNode);
                                    return nodeFlow(zcond,rootNode, list, nextNode);
                                }
//                                Iterator<Element> sunit = xnode.elementIterator();
//                                if (checkConds(sunit)) {//满足条件时
//                                    nextNodeId = xnode.attribute("targetRef").getValue();
//                                    System.out.println("条件分支转到:" + nextNodeId);
//                                    Znode nextNode = new Znode();
//                                    nextNode.setFacno(znode.getTarno());
//                                    nextNode.setFacna(znode.getTarna());
//                                    nextNode.setFacty("condtion");
//                                    nextNode.setTarno(nextNodeId);
//                                    list.add(nextNode);
//                                    return nodeFlow(rootNode, list, nextNode);
//                                }
                            }
                        }
                    }
                    break;
                }
            }
            if (!"".equals(userIds)) {
                break;
            }
        }
        return null;
    }
//
    private boolean checkConds(Zcond zcond,String expression) {
        System.out.println("条件为：" + expression);
        if(StrUtil.isBlank(expression)){
            return false;
        }

        String zformJson="";
        if(zcond!=null){
            System.out.println("modty:"+zcond.getModty());
            if("oaFlow".equals(zcond.getModty())){
                String sql="select zform id from oa_flow_main where id=?";
                zformJson = jdbcDao.findOneString(sql, zcond.getProid());
            }else if(zcond.getModty().startsWith("app_")){
                String sql="select cond from bpm_proc_cond where id=?";
                zformJson = jdbcDao.findOneString(sql, zcond.getProid());
            }

        }
        if (StrUtil.isBlank(zformJson))
        {
            zformJson = "{}";
        }
        String form = "var $=" + zformJson;
        System.out.println(form);
        CompiledScript script ;
        if(expression.contains(";")){
            script= ScriptUtil.compile(form+";var z=false;"+expression+";z");
        }else{
            script= ScriptUtil.compile(form+";var z="+expression+";z");
//            script= ScriptUtil.compile(expression);
        }
        boolean flag;
        try {
            flag= (boolean) script.eval();
        } catch (ScriptException e) {
            throw new ScriptRuntimeException(e);
        }
        System.out.println("返回结果="+flag);
        return flag;
    }

//    private boolean checkConds(Iterator<Element> it) {
//        while (it.hasNext()) {
//            Element son = it.next();
//            if ("extensionElements".equals(son.getName())) {
//                System.out.println("进入了：extensionElements");
//                Iterator<Element> sunit = son.elementIterator();
//                while (sunit.hasNext()) {
//                    Element sun = sunit.next();
//                    if ("executionListener".equals(sun.getName())) {
//                        System.out.println("进入了：executionListener");
//                        if (!checkCond(sun.attribute("expression").getValue())) {
//                            return false;
//                        }
//                        break;
//                    }
//                }
//                break;
//            }
//        }
//        return true;
//    }
//
//    private boolean checkCond(String expression) {
//        System.out.println("条件为：" + expression);
//        return true;
//    }

    public Znode getNodeInfo(String chxml, String facno) {
        SAXReader reader = new SAXReader();
        Reader stringReader = new StringReader(chxml);
        Document document = null;
        try {
            document = reader.read(stringReader);
        } catch (DocumentException e) {
            System.out.println("xml解析异常");
            e.printStackTrace();
        }
        Element rootNode = document.getRootElement();
        Iterator<Element> it = rootNode.elementIterator();
        while (it.hasNext()) {
            Element node = it.next();
            if ("userTask".equals(node.getName()) || "task".equals(node.getName())) {
                if (facno.equals(node.attribute("id").getValue())) {
                    Znode znode = new Znode();
                    znode.setFacno(facno);
                    znode.setFacna(node.attribute("name").getValue());
                    znode.setExmen(node.attribute("hamen")!=null?node.attribute("hamen").getValue():null);
                    znode.setFlway(node.attribute("flway")!=null?node.attribute("flway").getValue():null);
                    znode.setFacty("review");
                    return znode;
                }
            }
        }
        return null;
    }

    public Znode calcTarget(Zcond zcond,String chxml, String facno) {
        SAXReader reader = new SAXReader();
        Reader stringReader = new StringReader(chxml);
        Document document = null;
        try {
            document = reader.read(stringReader);
        } catch (DocumentException e) {
            System.out.println("xml解析异常");
            e.printStackTrace();
        }
        Element rootNode = document.getRootElement();
        Iterator<Element> it = rootNode.elementIterator();
        Znode currNode = new Znode();
        currNode.setFacno(facno);
        while (it.hasNext()) {
            Element node = it.next();
            if ("sequenceFlow".equals(node.getName())) {
                if (facno.equals(node.attribute("sourceRef").getValue())) {
                    currNode.setTarno(node.attribute("targetRef").getValue());
                    break;
                }
            }
        }
        List<Znode> list = new ArrayList<>();
        Znode nextNode = nodeFlow(zcond,rootNode, list, currNode);
        return nextNode;
    }

    public Znode getFirstNode(String xml, String facno) {
        //根据tmpid寻找xml的filename
        xml = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"
                + "\n<process" +
                xml.split("bpmn2:process")[1].replaceAll("bpmn2:", "").replaceAll("activiti:", "") + "process>";

        SAXReader reader = new SAXReader();
        Reader stringReader = new StringReader(xml);
        Document document = null;
        try {
            document = reader.read(stringReader);
        } catch (DocumentException e) {
            System.out.println("xml解析异常");
            e.printStackTrace();
        }
        Element rootNode = document.getRootElement();

        Znode currNode = new Znode();
        currNode.setFacno(facno);

        Iterator<Element> it = rootNode.elementIterator();
        while (it.hasNext()) {
            Element node = it.next();
            if ("sequenceFlow".equals(node.getName())) {
                if (facno.equals(node.attribute("sourceRef").getValue())) {
                    currNode.setTarno(node.attribute("targetRef").getValue());
                    break;
                }
            }
        }
        List<Znode> list = new ArrayList<>();
        Znode nextNode = nodeFlow(null,rootNode, list, currNode);
        return nextNode;
    }

    public List<ZidNamePid> GetAllLineList(String xml) {
        //根据tmpid寻找xml的filename
        xml = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"
                + "\n<process" +
                xml.split("bpmn2:process")[1].replaceAll("bpmn2:", "").replaceAll("activiti:", "") + "process>";

        SAXReader reader = new SAXReader();
        Reader stringReader = new StringReader(xml);
        Document document = null;
        try {
            document = reader.read(stringReader);
        } catch (DocumentException e) {
            System.out.println("xml解析异常");
            e.printStackTrace();
        }
        Element rootNode = document.getRootElement();

        List<ZidNamePid> list = new ArrayList<>();
        Iterator<Element> it = rootNode.elementIterator();
        while (it.hasNext()) {
            Element node = it.next();
            if ("sequenceFlow".equals(node.getName())) {
                ZidNamePid zinp = new ZidNamePid();
                zinp.setId(node.attribute("id").getValue() + "");
                zinp.setName(node.attribute("sourceRef").getValue() + "");
                zinp.setPid(node.attribute("targetRef").getValue() + "");
                list.add(zinp);
            }
        }
        return list;
    }

    @Autowired
    private JdbcDao jdbcDao;

}
